from PIL import Image, ImageDraw, ImageFont
import os
import math
from tools.FileExtensionUtil import FileExtensionUtil

class TxtToImg:
    def __init__(self):
        # 默认字体路径
        self.font_paths_yahei = [
            "C:\\Windows\\Fonts\\msyh.ttc",
            "C:\\Windows\\Fonts\\msyhbd.ttc"
        ]
        self.font_paths_yu = [
            "C:\\Windows\\Fonts\\YuGothM.ttc",
            "C:\\Windows\\Fonts\\YuGothB.ttc"
        ]
        self.default_font_size = 25
        self.default_width = 670
        self.default_height = 1100
        self.default_output_dir = r"C:\Users\33720\Desktop\temp"
        self.default_bgimg = r""
        self.lines_per_image = 25
        self.start_y = 40
        self.left_x = 40
    def load_font(self, paths, size):
        """依次尝试加载字体"""
        for path in paths:
            if os.path.exists(path):
                try:
                    return ImageFont.truetype(path, size)
                except Exception:
                    continue
        return None

    def can_render(self, char, font, verbose=False):
        """判断字体能否渲染指定字符"""
        try:
            bbox = font.getbbox(char)
            width = bbox[2] - bbox[0]
            height = bbox[3] - bbox[1]
            return width > 0 and (height > 0 or char.isspace())
        except Exception:
            return False

    def draw_with_fallback(self, draw, x, y, text, fonts, fill="black"):
        """逐字绘制文本，支持多字体回退"""
        pos_x = x
        for ch in text:
            for font in fonts:
                if self.can_render(ch, font):
                    draw.text((pos_x, y), ch, font=font, fill=fill)
                    pos_x += font.getlength(ch)
                    break
            else:
                draw.text((pos_x, y), "□", font=fonts[0], fill="gray")
                pos_x += fonts[0].getlength("□")

    def wrap_text(self, text, fonts, max_width):
        """
        自动换行：根据字体宽度将文本拆分成多行
        text: 原始字符串
        fonts: 字体列表
        max_width: 每行允许的最大宽度（像素）
        """
        lines = []
        current_line = ""
        current_width = 0
        font = fonts[0]  # 默认使用第一个字体测量宽度

        for ch in text:
            w = font.getlength(ch)
            if current_width + w > max_width:
                # 超过行宽 -> 换行
                lines.append(current_line)
                current_line = ch
                current_width = w
            else:
                current_line += ch
                current_width += w

        if current_line:
            lines.append(current_line)

        return lines

    def generate_images(self, text: str, width: int = None, height: int = None,
                        output_dir: str = None, font_size: int = None,
                        lines_per_image: int = None):
        """
        将多行文本字符串转换为图片

        Args:
            text: 多行文本字符串
            width: 图片宽度，默认670
            height: 图片高度，默认1100
            output_dir: 输出目录，默认桌面temp文件夹
            font_size: 字体大小，默认25
            lines_per_image: 每张图片行数，默认25

        """
        # 设置默认值
        width = width or self.default_width
        height = height or self.default_height
        output_dir = output_dir or self.default_output_dir
        font_size = font_size or self.default_font_size
        lines_per_image = lines_per_image or self.lines_per_image

        # 确保输出目录存在
        os.makedirs(output_dir, exist_ok=True)

        # 分割文本为行
        lines = text.splitlines()
        if not lines:
            print("⚠️ 文本为空，无法生成图片")
            return []

        # 加载字体
        font_yu = self.load_font(self.font_paths_yu, font_size)
        font_yahei = self.load_font(self.font_paths_yahei, font_size)
        fonts = [f for f in [font_yahei, font_yu] if f]

        if not fonts:
            print("⚠️ 未找到可用字体，请检查字体路径！")
            return []

        # 计算需要生成的图片数量
        total_images = math.ceil(len(lines) / lines_per_image)
        generated_paths = []

        # 每行高度
        line_height = fonts[0].getbbox("あ")[3] + 10
        start_y = self.start_y
        left_x = self.left_x
        usable_width = width - left_x * 2  # 可用宽度

        # 生成图片
        for idx in range(total_images):
            start = idx * lines_per_image
            end = start + lines_per_image
            chunk = lines[start:end]

            img = Image.new("RGB", (width, height), color="white")
            draw = ImageDraw.Draw(img)

            y = start_y
            for text_line in chunk:
                if text_line.strip() == "":
                    # 如果是空行，则只增加行高，不绘制文字
                    y += line_height
                    continue

                wrapped_lines = self.wrap_text(text_line, fonts, usable_width)
                for wrapped_line in wrapped_lines:
                    self.draw_with_fallback(draw, left_x, y, wrapped_line, fonts)
                    y += line_height

            # 保存图片
            output_path = os.path.join(output_dir, f"{idx:02d}.jpg")
            img.save(output_path)
            generated_paths.append(output_path)
            print(f"✅ 已生成：{output_path}")

        print(f"\n🎉 共生成 {total_images} 张图片，保存至：{os.path.abspath(output_dir)}")
        return "\n".join(generated_paths)

    def generate_images_backgroud(self, text: str, width: int = None, height: int = None,
                                  output_dir: str = None, font_size: int = None,
                                  lines_per_image: int = None):
        """
        将多行文本字符串转换为图片（支持自定义背景）

        Args:
            text: 多行文本字符串
            width: 图片宽度，默认670
            height: 图片高度，默认1100
            output_dir: 输出目录，默认桌面temp文件夹
            font_size: 字体大小，默认25
            lines_per_image: 每张图片行数，默认25
            background_image_path: 背景图片路径，如果为None则使用白色背景
        """
        # 设置默认值
        width = width or self.default_width
        height = height or self.default_height
        output_dir = output_dir or self.default_output_dir
        font_size = font_size or self.default_font_size
        lines_per_image = lines_per_image or self.lines_per_image

        # 确保输出目录存在
        os.makedirs(output_dir, exist_ok=True)

        # 分割文本为行
        lines = text.splitlines()
        if not lines:
            print("⚠️ 文本为空，无法生成图片")
            return []

        # 加载字体
        font_yu = self.load_font(self.font_paths_yu, font_size)
        font_yahei = self.load_font(self.font_paths_yahei, font_size)
        fonts = [f for f in [font_yahei, font_yu] if f]

        if not fonts:
            print("⚠️ 未找到可用字体，请检查字体路径！")
            return []

        # 计算需要生成的图片数量
        total_images = math.ceil(len(lines) / lines_per_image)
        generated_paths = []

        # 每行高度
        line_height = fonts[0].getbbox("あ")[3] + 10
        start_y = self.start_y
        left_x = self.left_x
        usable_width = width - left_x * 2  # 可用宽度

        # 加载背景图片（如果有）
        background_image_path = ""
        background_image = None
        if self.default_bgimg != "":
            background_image_path = self.default_bgimg
            print("背景图片:" + background_image_path)
        if background_image_path and os.path.exists(background_image_path):
            try:
                background_image = Image.open(background_image_path)
                # 调整背景图片尺寸
                background_image = background_image.resize((width, height))
                print(f"✅ 已加载背景图片：{background_image_path}")
            except Exception as e:
                print(f"⚠️ 加载背景图片失败：{e}，将使用白色背景")
                background_image = None

        # 生成图片
        for idx in range(total_images):
            start = idx * lines_per_image
            end = start + lines_per_image
            chunk = lines[start:end]

            # 创建图片：使用背景图片或白色背景
            if background_image:
                # 复制背景图片作为底图
                img = background_image.copy()
            else:
                # 使用白色背景
                img = Image.new("RGB", (width, height), color="white")

            draw = ImageDraw.Draw(img)

            y = start_y
            for text_line in chunk:
                if text_line.strip() == "":
                    # 如果是空行，则只增加行高，不绘制文字
                    y += line_height
                    continue

                wrapped_lines = self.wrap_text(text_line, fonts, usable_width)
                for wrapped_line in wrapped_lines:
                    self.draw_with_fallback(draw, left_x, y, wrapped_line, fonts)
                    y += line_height

            # 添加编号到最后一行的中心位置
            # 编号格式：当前页码/总页数 (例如：1/5, 2/5, ...)
            page_number = f"{idx + 1}/{total_images}"

            # 使用相同的字体绘制编号
            # 计算编号文本的尺寸
            try:
                # 尝试使用第一个字体获取文本尺寸
                bbox = fonts[0].getbbox(page_number)
                text_width = bbox[2] - bbox[0]
                text_height = bbox[3] - bbox[1]
            except:
                # 备用方法计算文本尺寸
                text_width = len(page_number) * font_size
                text_height = font_size

            # 计算编号位置（底部居中，留出一些边距）
            bottom_margin = 20  # 底部边距
            number_x = (width - text_width) // 2  # 水平居中
            number_y = height - text_height - bottom_margin  # 底部位置

            # 绘制编号
            self.draw_with_fallback(draw, number_x, number_y, page_number, fonts)

            # 保存图片
            output_path = os.path.join(output_dir, f"{idx:02d}.png")
            if FileExtensionUtil.get_extension(background_image_path, False) == "jpg":
                img = img.convert('RGB')  # 需要重新赋值
            img.save(output_path)
            generated_paths.append(output_path)
            print(f"✅ 已生成：{output_path}")

        return "\n".join(generated_paths)

    def set_default_font_size(self, size: int):
        """设置默认字体大小"""
        self.default_font_size = size

    def set_default_width(self, width: int):
        """设置默认图片尺寸"""
        self.default_width = width

    def set_default_height(self, height: int):
        """设置默认图片尺寸"""

        self.default_height = height

    def set_default_output_dir(self, directory: str):
        """设置默认输出目录"""
        self.default_output_dir = directory

    def set_lines_per_image(self, lines: int):
        """设置每张图片的行数"""
        self.lines_per_image = lines

    def set_bgimg(self, img: str):
        """设置每张图片的行数"""
        self.default_bgimg = img

    def set_starty(self, starty: int):
        """设置每张图片的行数"""
        self.start_y=starty

    def set_leftx(self, leftx: int):
        """设置每张图片的行数"""
        self.left_x=leftx

    def to_str(self):
        """获取当前配置"""
        return {
            "font_size": self.default_font_size,
            "width": self.default_width,
            "height": self.default_height,
            "output_dir": self.default_output_dir,
            "lines_per_image": self.lines_per_image,
            "bgimg": self.default_bgimg
        }


# 使用示例
def main():
    # 创建生成器实例
    generator = TxtToImg()

    # 示例1：使用默认参数
    text = """这是第一行
这是第二行
这是第三行
...
这是最后一行"""

    # 生成图片
    image_paths = generator.generate_images(text)
    print(f"生成的图片: {image_paths}")

    # 示例2：自定义参数
    custom_text = """自定义文本
宽度800，高度1200
字体大小30
每张图片20行"""

    image_paths = generator.generate_images(
        text=custom_text,
        width=800,
        height=1200,
        font_size=30,
        lines_per_image=20,
        output_dir=r"C:\Users\33720\Desktop\custom_images"
    )

    # 示例3：修改默认设置
    generator.set_default_font_size(28)
    generator.set_default_dimensions(750, 1000)
    generator.set_default_output_dir(r"C:\Users\33720\Desktop\my_images")

    # 使用新默认设置生成图片
    image_paths = generator.generate_images(text)


if __name__ == "__main__":
    main()
